# -*- coding: utf-8 -*-
"""
@ Created on 2024-06-14 12:23
---------
@summary: 字典项CRUD操作
---------
@author: Lsaiah
"""

from tortoise import fields
from tortoise.models import Model
from tortoise.contrib.pydantic import pydantic_model_creator
from datetime import datetime
from typing import Optional, List, Dict, Any


class DictItem(Model):
    """字典项模型"""
    id = fields.IntField(pk=True, description="字典项ID")
    dict_type = fields.ForeignKeyField("models.DictType", related_name="items", on_delete=fields.CASCADE, db_field="dict_type_id", description="字典类型")
    label = fields.CharField(max_length=100, description="字典项标签")
    value = fields.CharField(max_length=100, description="字典项值")
    description = fields.CharField(max_length=200, null=True, description="字典项描述")
    is_active = fields.BooleanField(default=True, description="是否激活")
    sort_order = fields.IntField(default=0, description="排序")
    created_at = fields.DatetimeField(auto_now_add=True, description="创建时间")
    updated_at = fields.DatetimeField(auto_now=True, description="更新时间")

    class Meta:
        table = "system_dict_item"
        table_description = "系统字典项表"

    def __str__(self):
        return f"DictItem(id={self.id}, label={self.label}, value={self.value})"


# Pydantic 模型
DictItem_Pydantic = pydantic_model_creator(DictItem, name="DictItem")
DictItemIn_Pydantic = pydantic_model_creator(
    DictItem, 
    name="DictItemIn", 
    exclude_readonly=True,
    exclude=("id", "created_at", "updated_at")
)
DictItemUpdate_Pydantic = pydantic_model_creator(
    DictItem, 
    name="DictItemUpdate", 
    exclude_readonly=True,
    exclude=("id", "created_at", "updated_at")
)


class DictItemCRUD:
    """字典项CRUD操作类"""
    
    @staticmethod
    async def create(data: Dict[str, Any]) -> DictItem:
        """创建字典项"""
        # 验证字典类型是否存在并处理外键关系
        if 'dict_type_id' in data:
            from ..curd.dict_type_crud import DictType
            dict_type = await DictType.get_or_none(id=data['dict_type_id'])
            if not dict_type:
                raise ValueError(f"字典类型ID {data['dict_type_id']} 不存在")
            # 将 dict_type_id 转换为 dict_type 对象
            data['dict_type'] = dict_type
            del data['dict_type_id']
        
        return await DictItem.create(**data)
    
    @staticmethod
    async def get_by_id(id: int) -> Optional[DictItem]:
        """根据ID获取字典项"""
        return await DictItem.get_or_none(id=id)
    
    @staticmethod
    async def get_by_dict_type_id(dict_type_id: int) -> List[DictItem]:
        """根据字典类型ID获取字典项列表"""
        return await DictItem.filter(dict_type_id=dict_type_id, is_active=True).order_by("sort_order")
    
    @staticmethod
    async def get_list_all() -> List[DictItem]:
        """根据字典ID获取字典项列表"""
        return await DictItem.all()
    
    @staticmethod
    async def get_list(
        skip: int = 0, 
        limit: int = 10, 
        search: Optional[str] = None,
        **filters
    ) -> List[DictItem]:
        """获取字典项列表"""
        query = DictItem.all()
        
        if search:
            query = query.filter(
                label__icontains=search
            ) | query.filter(
                value__icontains=search
            ) | query.filter(
                description__icontains=search
            )
        
        # 处理其他过滤条件
        for key, value in filters.items():
            if value is not None:
                query = query.filter(**{key: value})
        
        return await query.offset(skip).limit(limit).order_by("sort_order", "-created_at")
    
    @staticmethod
    async def count_list(
        search: Optional[str] = None,
        **filters
    ) -> int:
        """统计字典项数量"""
        query = DictItem.all()
        
        if search:
            query = query.filter(
                label__icontains=search
            ) | query.filter(
                value__icontains=search
            ) | query.filter(
                description__icontains=search
            )
        
        # 处理其他过滤条件
        for key, value in filters.items():
            if value is not None:
                query = query.filter(**{key: value})
        
        return await query.count()
    
    @staticmethod
    async def update(id: int, update_data: Dict[str, Any]) -> Optional[DictItem]:
        """更新字典项"""
        dict_item = await DictItem.get_or_none(id=id)
        if dict_item:
            await dict_item.update_from_dict(update_data)
            await dict_item.save()
        return dict_item
    
    @staticmethod
    async def delete(id: int) -> bool:
        """删除字典项"""
        dict_item = await DictItem.get_or_none(id=id)
        if dict_item:
            await dict_item.delete()
            return True
        return False
